/**
 * 
 */
package com.game.astd.spirit;

import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import com.game.astd.spirit.inter.TaskUnit;

/**
 * @author beedoorwei
 * 
 */
public class TaskManager
{
	static ScheduledExecutorService exec = Executors.newScheduledThreadPool(10);

	// 此处提交任务将查看是否有同类任务，如果有同类任务则不再提交
	static Map<Integer, ConcurrentHashMap<String, TU>> sycQueueMap = new ConcurrentHashMap<Integer, ConcurrentHashMap<String, TU>>();

	static
	{
		exec.scheduleAtFixedRate(new TaskSchedule(), 0, 1, TimeUnit.SECONDS);
	}

	/**
	 * 提交一个按指定频率执行的任务
	 * 
	 * @param r
	 * @param s
	 * @param d
	 * @param t
	 */
	public static void addTaskAtFixedRate(TaskUnit r, int s, int d, TimeUnit t)
	{
		exec.scheduleAtFixedRate(r, s, d, t);
	}

	/**
	 * 提交一个任务，该任务将直接执行
	 * 
	 * @param r
	 */
	public static void addTask(TaskUnit r)
	{
		addTask(r, 0);
	}

	/**
	 * 提交一个指定时间后开始执行的任务
	 * 
	 * @param r
	 * @param delay
	 *            时间间隔，间隔单位是秒i
	 */
	public static void addTask(TaskUnit r, int delay)
	{
		if (!sycQueueMap.containsKey(r.getGid()))
		{
			sycQueueMap.put(r.getGid(), new ConcurrentHashMap<String, TU>());
		}
		ConcurrentHashMap<String, TU> userTaskMap = sycQueueMap.get(r.getGid());
		if (!userTaskMap.containsKey(r.getClass().getName()))
		{
			LoggerUtil.info(r.getGid(),r.getClass().getName() + " 任务加入到工作队列 ," + GameUtil.getRemainTime(delay * 1000 + "") + "后启动");
			userTaskMap.put(r.getClass().getName(), new TU(delay, r));
		} else
		{
			TU t = userTaskMap.get(r.getClass().getName());
			if (t.getTime() + t.getDelay() > System.currentTimeMillis() + delay * 1000)
			{
				// 当前任务的执行时间，比队列中的任务执行时间距离目前近，删除队列中的，保留当前
				userTaskMap.put(r.getClass().getName(), new TU(delay, r));
				LoggerUtil.info(r.getGid(), r.getClass().getName() + " 已更新");
			} else
			{
				// 查看时间吧，如过现在这个任务的时间比队列中的近，则优先执行该任务，将原来的任务停掉
				LoggerUtil.info(r.getGid(), r.getClass().getName() + " 任务已经提交过，无需重复提交");
			}

		}
	}

	public static void addTask(Runnable r, int s, int d, TimeUnit t)
	{
		exec.scheduleAtFixedRate(r, s, d, t);
	}

	public static void removeTask(TaskUnit r)
	{
		ConcurrentHashMap<String, TU> userTaskMap = sycQueueMap.get(r.getGid());
		if (!userTaskMap.containsKey(r.getClass().getName()))
		{
			LoggerUtil.info(r.getGid(), r.getClass().getName() + " 任务移除任务队列");
			userTaskMap.remove(r.getClass().getName());
		}
	}

}

class TaskSchedule implements Runnable
{
	public void run()
	{
		Iterator<Integer> ar = TaskManager.sycQueueMap.keySet().iterator();
		while (ar.hasNext())
		{
			Integer key = ar.next();
			ConcurrentHashMap<String, TU> userTaskMap = TaskManager.sycQueueMap.get(key);
			if (userTaskMap != null)
			{
				Iterator<String> ar2 = userTaskMap.keySet().iterator();
				while (ar2.hasNext())
				{
					String key2 = ar2.next();
					TU tUnit = userTaskMap.get(key2);
					if (tUnit.getTime() + tUnit.getDelay() < System.currentTimeMillis())
					{
						// 过点了， 开始执行咯
						TaskManager.exec.submit(tUnit.t);
						userTaskMap.remove(key2);
						LoggerUtil.info(tUnit.t.getGid(),tUnit.t.getClass().getName() + " 开始执行");
					}
				}
			}
		}

	}
}

class TU
{
	public long time = System.currentTimeMillis();
	public long delay;
	public TaskUnit t;

	public TU(long delay, TaskUnit t)
	{
		super();
		this.delay = delay * 1000;
		this.t = t;
	}

	public long getTime()
	{
		return time;
	}

	public void setTime(long time)
	{
		this.time = time;
	}

	public long getDelay()
	{
		return delay;
	}

	public void setDelay(long delay)
	{
		this.delay = delay;
	}

	public TaskUnit getT()
	{
		return t;
	}

	public void setT(TaskUnit t)
	{
		this.t = t;
	}

}
